import lombok.Data;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import java.util.Vector;

@Data
public class MyPanel extends JPanel implements KeyListener, Runnable {

    private MyTank myTank = null;
    private Vector<EnemyTank> enemyTanks = new Vector<>();
    private Vector<Node> nodes = new Vector<>();
    private Vector<Bomb> bombs = new Vector<>();
    private int enSize = 3;
    private Image image1 = null;
    private Image image2 = null;
    private Image image3 = null;

    public MyPanel(String flag,String path) {
        Recorder.getRecording(path);
        myTank = new MyTank(100, 100);
        if (flag.equals("NewGame")) {
            for (int i = 0; i < enSize; i++) {
                EnemyTank enemyTank = new EnemyTank((i + 1) * 50, 0);
                enemyTank.setColor(0);
                enemyTank.setDirect(2);
                enemyTank.setEnemyTanks(enemyTanks);
                Thread thread = new Thread(enemyTank);
                thread.start();

                Shot shot = new Shot(enemyTank.getX() + 10, enemyTank.getY() + 30, 2);
                enemyTank.getShots().add(shot);
                Thread thread1 = new Thread(shot);
                thread1.start();
                enemyTanks.add(enemyTank);

            }

        } else {
            System.out.println("接着玩");
            nodes = new Recorder().getNodeAndEnNums(path);
            //初始化敌人的坦克
            for (int i = 0; i < nodes.size(); i++) {
                Node node = nodes.get(i);
                //创建一辆敌人的坦克对象
                EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());
                enemyTank.setColor(0);
                enemyTank.setDirect(node.getDirect());
                // 将panel的敌人坦克向量交给敌人坦克
                enemyTank.setEnemyTanks(enemyTanks);
                // 启动敌人的坦克
                Thread thread = new Thread(enemyTank);
                thread.start();
                // 给敌人的坦克添加一颗子弹
                Shot shot = new Shot(enemyTank.getX() + 10, enemyTank.getY() + 30, 2);
                // 加入给敌人坦克
                enemyTank.getShots().add(shot);
                Thread thread1 = new Thread(shot);
                thread1.start();
                enemyTanks.add(enemyTank);
            }
        }
        try {
            image1 = ImageIO.read(new File(path+"/bomb_1.gif"));
            image2 = ImageIO.read(new File(path+"/bomb_2.gif"));
            image3 = ImageIO.read(new File(path+"/bomb_3.gif"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        AePlayWave aePlayWave = new AePlayWave(path+"/111.wav");
        aePlayWave.start();

    }

    public void showInfo(Graphics graphics) {
        this.drawTank(80, 330, graphics, 0, 0);
        graphics.setColor(Color.BLACK);
        graphics.drawString(Recorder.getEnNum() + "", 110, 350);
        this.drawTank(130, 330, graphics, 0, 1);
        graphics.setColor(Color.BLACK);
        graphics.drawString(Recorder.getMyLife() + "", 165, 350);

        //画出玩家总成绩
        graphics.setColor(Color.BLACK);
        Font font = new Font("宋体", Font.BOLD, 20);
        graphics.setFont(font);
        graphics.drawString("你的总成绩：", 420, 30);
        this.drawTank(420, 60, graphics, 0, 0);
        graphics.setColor(Color.BLACK);
        graphics.drawString(Recorder.getAllEnNum() + "", 460, 80);


    }

    public void paint(Graphics graphics) {

        super.paint(graphics);
        graphics.fillRect(0, 0, 400, 300);
        this.showInfo(graphics);


        //画出自己的坦克
        if (myTank.isLive()) {

            this.drawTank(myTank.getX(), myTank.getY(), graphics, myTank.getDirect(), 1);

        }
        // 取出每颗子弹并画出
        for (int i = 0; i < myTank.getShots().size(); i++) {
            Shot shot = myTank.getShots().get(i);
            if (shot != null && shot.isLive()) {
                graphics.draw3DRect(shot.getX(), shot.getY(), 1, 1, false);
            }

            if (!shot.isLive()) {
                myTank.getShots().remove(shot);
            }
        }
        // 画出炸弹
        for (int i = 0; i < bombs.size(); i++) {
            System.out.println("bombs.size()="+bombs.size());
            Bomb bomb = bombs.get(i);
            if (bomb.getLife() > 6) {
                graphics.drawImage(image1, bomb.getX(), bomb.getY(), 30, 30, this);
            } else if (bomb.getLife() > 3) {
                graphics.drawImage(image2, bomb.getX(), bomb.getY(), 30, 30, this);
            } else {
                graphics.drawImage(image3, bomb.getX(), bomb.getY(), 30, 30, this);
            }
            // 让炸弹的生命值减小
            bomb.lifeDown();
            // 如果炸弹的生命值为0，就该把炸弹从集合中去掉
            if (bomb.getLife() == 0) {
                bombs.remove(bomb);
            }

        }
        // 画出敌人的坦克

        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            if (enemyTank.isLive()) {
                this.drawTank(enemyTank.getX(), enemyTank.getY(), graphics, enemyTank.getDirect(), 0);
                // 画出敌人的子弹
                System.out.println("坦克子弹有:"+enemyTank.getShots().size());
                for (int j = 0; j < enemyTank.getShots().size(); j++) {
                    Shot shot = enemyTank.getShots().get(j);
                    if (shot.isLive()) {
                        graphics.draw3DRect(shot.getX(), shot.getY(), 1, 1, false);
                    } else {
                        /// 如果敌人的坦克死亡就移除
                        enemyTank.getShots().remove(shot);
                    }
                }
            }
        }
    }

    public void drawTank(int x, int y, Graphics graphics, int direct, int type) {
        switch (type) {// 判断是什么类型的坦克
            case 0:
                graphics.setColor(Color.cyan);
                break;
            case 1:
                graphics.setColor(Color.yellow);
                break;

        }
        switch (direct) {
            case 0: // 炮筒向上
                //画出我的坦克
                //1.画出左边的矩形
                graphics.fill3DRect(x, y, 5, 30, false);
                //2.画出右边的矩形
                graphics.fill3DRect(x + 15, y, 5, 30, false);
                //3.画出中间矩形
                graphics.fill3DRect(x + 5, y + 5, 10, 20, false);
                //4.画出圆形
                graphics.fillOval(x + 5, y + 10, 10, 10);
                //5.画出线
                graphics.drawLine(x + 10, y + 15, x + 10, y);
                break;
            case 1:
                //1.画出左边的矩形
                graphics.fill3DRect(x, y, 30, 5, false);
                //2.画出右边的矩形
                graphics.fill3DRect(x, y + 15, 30, 5, false);
                //3.画出中间矩形
                graphics.fill3DRect(x + 5, y + 5, 20, 10, false);
                //4.画出圆形
                graphics.fillOval(x + 10, y + 5, 10, 10);
                //5.画出线
                graphics.drawLine(x + 15, y + 10, x + 30, y + 10);
                break;
            case 2:
                //1.画出左边的矩形
                graphics.fill3DRect(x, y, 5, 30, false);
                //2.画出右边的矩形
                graphics.fill3DRect(x + 15, y, 5, 30, false);
                //3.画出中间矩形
                graphics.fill3DRect(x + 5, y + 5, 10, 20, false);
                //4.画出圆形
                graphics.fillOval(x + 5, y + 10, 10, 10);
                //5.画出线
                graphics.drawLine(x + 10, y + 15, x + 10, y + 30);
                break;
            case 3:
                //1.画出左边的矩形
                graphics.fill3DRect(x, y, 30, 5, false);
                //2.画出右边的矩形
                graphics.fill3DRect(x, y + 15, 30, 5, false);
                //3.画出中间矩形
                graphics.fill3DRect(x + 5, y + 5, 20, 10, false);
                //4.画出圆形
                graphics.fillOval(x + 10, y + 5, 10, 10);
                //5.画出线
                graphics.drawLine(x + 15, y + 10, x, y + 10);
                break;
        }

    }

    @Override
    public boolean getInheritsPopupMenu() {
        return super.getInheritsPopupMenu();
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    // 键盘按键处理 a表示向左 s 表示下 w 表示上 d 表示右
    @Override
    public void keyPressed(KeyEvent e) {


        if (e.getKeyCode() == KeyEvent.VK_W) {
            this.myTank.setDirect(0);
            this.myTank.moveUp();
        } else if (e.getKeyCode() == KeyEvent.VK_D) {
            this.myTank.setDirect(1);
            this.myTank.moveRight();
        } else if (e.getKeyCode() == KeyEvent.VK_S) {
            this.myTank.setDirect(2);
            this.myTank.moveDown();
        } else if (e.getKeyCode() == KeyEvent.VK_A) {
            this.myTank.setDirect(3);
            this.myTank.moveLeft();
        }

        if (e.getKeyCode() == KeyEvent.VK_J) {
            // 判断玩家是否按下J键
            if (this.myTank.getShots().size() <= 4) {
                this.myTank.shotEnemy();
            }
        }
        // 必须重新绘制Panel
        this.repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {
        //  每隔100毫秒去重绘
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //判断是否击中敌人
            this.hitEnemyTank();
            // 判断是否击中自己
            this.hitMe();
            //重绘
            this.repaint();
        }

    }

    // 判断敌人是否击中我
    private void hitMe() {
        for (int i = 0; i < this.enemyTanks.size(); i++) {

            EnemyTank enemyTank = enemyTanks.get(i);
            for (int j = 0; j < enemyTank.getShots().size(); j++) {
                Shot shot = enemyTank.getShots().get(j);
                if (myTank.isLive()) {
                    this.hitTank(shot, myTank);
                }
            }
        }

    }

    // 判断我的子弹是否击中敌人坦克
    private void hitEnemyTank() {

        for (int i = 0; i < myTank.getShots().size(); i++) {
            // 取出子弹
            Shot shot = myTank.getShots().get(i);
            //判断子弹是否有效
            if (shot.isLive()) {

                for (int j = 0; j < enemyTanks.size(); j++) {
                    //取出坦克
                    EnemyTank enemyTank = enemyTanks.get(j);
                    if (enemyTank.isLive()) {

                        if (this.hitTank(shot, enemyTank)) {// 判断是否击中
                            //减少敌人数量
                            Recorder.reduceEnNum();
                            //增加我的消灭敌人数量记录
                            Recorder.addAllEnNum();
                        }
                    }
                }
            }
        }

    }

    private boolean hitTank(Shot shot, Tank enemyTank) {

        boolean flag = false;
        switch (enemyTank.getDirect()) {
            case 0:
            case 2:// 如果敌人谈的方向是上或下
                if (shot.getX() > enemyTank.getX() && shot.getX() < enemyTank.getX() + 20 &&
                        shot.getY() > enemyTank.getY() && shot.getY() < enemyTank.getY() + 30) {
                    // 击中
                    //子弹死亡
                    shot.setLive(false);
                    enemyTank.setLive(false);
                    flag = true;
                    Bomb b = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombs.add(b);
                }
                break;
            case 1:
            case 3: // 如果敌人坦克的方向是左或者右
                if (shot.getX() > enemyTank.getX() && shot.getX() < enemyTank.getX() + 30 &&
                        shot.getY() > enemyTank.getY() && shot.getY() < enemyTank.getY() + 20) {
                    // 击中
                    //子弹死亡
                    shot.setLive(false);
                    enemyTank.setLive(false);
                    flag = true;
                    Bomb b = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombs.add(b);
                }
                break;
        }
        return flag;
    }
}
